home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 4
/
United Public Domain Gold 4.iso
/
fredfish
/
ff.0773.dms
/
ff.0773.adf
/
REXXProgs
/
Palette.rexx
next >
Wrap
OS/2 REXX Batch file
|
1992-12-05
|
14KB
|
720 lines
/* $VER: 1.0 Palette.rexx 7 Dec 1991 (7.12.91)
copyright 1991 Richard Lee Stockton and Gramma Software.
FREELY DISTRIBUTABLE as long as this notice remains
USAGE: rx Palette [public_screen] [colors] [replyport]
defaults to Workbench with 4 colors, no replyport
ASYNCH example: ADDRESS AREXX Palette MY8COLORSCREEN 8 MYPORT
Palette.rexx will return 5 if the user selects "USE" and if
Palette.rexx was given a replyport name, the message 'NEW_COLORS'
is sent to the replyport. Otherwise no message is sent and the
function returns 0.
WARNING! There is no way to check to see if colors is the correct
number for a particular screen. Colors *MUST* be either 2, 4, 8,
16, or 32, and too large a number will cause the requester to fail!
requires these external libraries:
arp.library
rexxsupport.library
rexxarplib.library
screenshare.library
Author's Note:
I have tried to include plenty of comments in the hope that someone
might use it as a starting point for their own application. Hack away!
*/
/*
make sure the needed libraries are available, and away we go!
*/
IF ~SHOW('L','rexxsupport.library') THEN
CALL ADDLIB('rexxsupport.library',0,-30,0)
IF ~SHOW('L','rexxarplib.library') THEN
CALL ADDLIB('rexxarplib.library',0,-30,0)
/*
We'll need to know what OS version and what CPU
*/
CALL getversions()
/*
get arguments and/or set defaults
*/
PARSE ARG pscreen' 'colors' 'replyport .
IF colors~=2 & colors~=8 & colors~=16 & colors~=32 THEN colors=4
/*
Under 2.0, "Workbench" is a Public_Screen so we can use the Palette.
Under 1.3, Palette needs a custom screenshare screen.
*/
IF pscreen='' THEN pscreen='Workbench'
IF pscreen='Workbench' & ksversion<37 THEN
CALL ALL_DONE('Can not open Palette on pre-2.0 WorkBench!')
/*
Find a free hostport. Multiple invocations may co-exist on the
same or multiple screens, but only one palette per replyport.
In that case, tell that palette to come to the front.
*/
host='PALETTEHOST'
port='PALETTEPORT'
IF replyport='' THEN
DO
DO i=1 WHILE SHOW('P',host||i)
END
host=host||i
port=port||i
END
ELSE
DO
host=host'.'replyport
port=port'.'replyport
IF SHOW('P',port) THEN
DO
INTERPRET ADDRESS port FRONT
EXIT(0)
END
END
/*
take care of mundane stuff
*/
CALL setup_variables()
/*
We need a HOST to set up our window in
*/
CALL setup_host()
/*
open the window with menus and gadgets and graphics, oh my!
Note the CLOSEWINDOW WINDOWCLOSE pair. w.flags tells the HOST
what gadgets we want, w.idcmp tells it what kinds of messages
we want to recieve.
*/
w.=''
w.idcmp='CLOSEWINDOW+MENUPICK+GADGETDOWN+GADGETUP+MOUSEBUTTONS'
w.flags='WINDOWCLOSE+WINDOWDRAG'
/*
If we have a replyport we can identify it in the title. The
extra spaces at the end are to fill out the rest of the 1.3
titleline. Under 2.0 these spaces are not necessary.
*/
w.title=' ARexx Color Palette '
IF replyport~='' THEN w.title=' 'replyport' Colors '
/*
Note how the palette always opens centered in the screen
This is easier to do with a rexxarplib window as opposed to
a requester since Request() is auto-magically sized.
Also note how you can continue a line of sourcecode simply by
adding an extra "," at the end of any line that is continued.
*/
xmax=218
ymax=126
CALL OpenWindow(host,(ScreenCols(pscreen)-xmax)%2, ,
(ScreenRows(pscreen)-ymax)%2, ,
xmax,ymax,w.idcmp,w.flags,w.title)
/*
Make sure our text images will be correct, no matter what...
*/
CALL SetFont(host,'topaz.font',8)
/*
Try to adjust a little for 1.3 by changing color registers
*/
p1=1
p2=2
IF ksversion<37 THEN
DO
p1=2
p2=1
CALL SetReqColor(host,'OKAYPEN',1)
END
/*
Add X and Y position to the message that MOUSEBUTTONS sends.
Now instead of plain MOUSEBUTTONS messages, we get SELECTUP
or SELECTDOWN and the location, ie, "SELECTUP 267 59".
If the mouse is over a gadget the appropriate GADGET message
is sent instead.
*/
CALL ModifyHost(host,MOUSEBUTTONS,"%b %x %y")
/*
Menu - AddMenu(host, text, message, hotkey)
*/
CALL AddMenu(host,'ARexx Palette')
CALL AddItem(host,'Use ','OK','U')
CALL AddItem(host,'Reset ','RESET','R')
CALL AddItem(host,'About ','ABOUT')
CALL AddItem(host,'Quit ','CLOSEWINDOW','Q')
/*
Gadgets - AddGadget(host, left, top, gadget_id, text, message)
6 color adjuster Gadgets, 2 each for the Red Green and Blue guns.
*/
CALL AddGadget(host,15,26,1,'<','%l 1 -1')
CALL AddGadget(host,51,26,2,'>','%l 1 1')
CALL AddGadget(host,85,26,3,'<','%l 2 -1')
CALL AddGadget(host,121,26,4,'>','%l 2 1')
CALL AddGadget(host,155,26,5,'<','%l 3 -1')
CALL AddGadget(host,191,26,6,'>','%l 3 1')
/*
Labels for the color adjust gadgets
*/
CALL SetAPen(host,1)
CALL Move(host,27,22)
CALL Text(host,'Red')
CALL Move(host,89,22)
CALL Text(host,'Green')
CALL Move(host,163,22)
CALL Text(host,'Blue')
/*
A little graphics to make everything look nicer.
box(host,upleft_color,bottomright_color,leftedge,topedge,width,height)
*/
DO i=1 TO 3
CALL box(host,p1,p1,8+(i-1)*70,13,61,26)
END
CALL box(host,p1,p2,53,42,108,10)
CALL box(host,p1,p1,15,55,186,50)
CALL read_colors()
/*
get the current colors from the screen
*/
CALL read_colors()
/*
system-type gadgets
*/
CALL AddGadget(host,11,ymax-16,98,' USE ','OK')
CALL AddGadget(host,xmax%2-24,ymax-16,99,'RESET','RESET')
CALL AddGadget(host,xmax-64,ymax-16,99,'CANCEL','CLOSEWINDOW')
/*
bring this window to the front and activate it
*/
CALL tofront()
/*
MAIN message loop
*/
keep_going=1
DO WHILE keep_going=1
/*
Wait for at least one message to arrive
*/
t=WAITPKT(port)
/*
process *ALL* the messages waiting at this port
*/
DO ff=1
p=GETPKT(port)
/*
p=NULL means not more messages at this port.
This is the *ONLY* time you should leave this loop!
*/
IF p='0000 0000'x THEN LEAVE ff /* message port empty */
/*
get the message from the the port packet
*/
command=GETARG(p)
/*
REPLY() as soon as you can, as soon as you are through extracting
data from the packet with GETARG()
*/
t=REPLY(p,0)
/*
Ignore any messages received after the CLOSEWINDOW
*/
IF keep_going=0 THEN ITERATE ff
/*
now we can see what the message contains, and act on it
*/
PARSE VAR command arg1' 'arg2' 'arg3' '
SELECT
WHEN arg1='CLOSEWINDOW' THEN keep_going=0
WHEN arg1='RESET' THEN CALL reset_colors()
WHEN arg1='OK' THEN CALL do_ok()
WHEN arg1='FRONT' THEN CALL tofront()
WHEN arg1='GADGETDOWN' THEN CALL gadgetdown(arg2 arg3)
WHEN arg1='SELECTDOWN' THEN CALL selectdown(arg2 arg3)
WHEN arg1='ABOUT' THEN CALL Request(,,copyright,,,,pscreen)
WHEN arg1='GADGETUP' THEN NOP
WHEN arg1='SELECTUP' THEN NOP
WHEN arg1='CONTINUE' THEN NOP
/*
display all messages not otherwise handled in this select loop so
we can see what is happening when things go wrong.
This is a good debugging OTHERWISE for any SELECT loop.
*/
OTHERWISE CALL REQUEST(,100,arg1 arg2 arg3,,,,pscreen)
END
END
END
CALL ALL_DONE('RESET')
EXIT(0)
/* Functions */
/*
send all endings thru here so we can clean up
*/
ALL_DONE:
PARSE ARG air
changed=0
CALL PostMsg()
IF air='RESET' THEN CALL reset_colors()
ELSE IF air='NEW_COLORS' THEN changed=5
ELSE IF air~='' THEN
DO
CALL usermsg(air)
CALL waiting()
END
CALL clearport(port)
IF SHOW('P',host) THEN CALL Stop(host)
EXIT(changed)
RETURN
/*
remove all waiting messages from a port.
In most cases this shouldn't be required if you have handled
your message port loop properly. Doesn't hurt though.....-)
*/
clearport:
PARSE ARG portname
p=1
DO FOREVER
p=GETPKT(portname)
IF p='0000 0000'x THEN RETURN
t=REPLY(p,0)
END
RETURN
/*
Colors accepted, send message to replyport and quit
*/
do_ok:
IF replyport~='' THEN
IF SHOWLIST('P',replyport) THEN
INTERPRET ADDRESS replyport 'NEW_COLORS'
CALL ALL_DONE('NEW_COLORS')
RETURN
tofront:
CALL ActivateWindow(host)
CALL WindowToFront(host)
CALL ScreenToFront(pscreen)
RETURN
/*
set box-size and put colors in the selection area
also stores the currently displayed colors in the stem "colors."
*/
read_colors:
colors.=''
box_x=92
box_y=48
IF colors>8 THEN
DO
box_y=12
box_x=46
IF colors=32 THEN box_x=23
END
ELSE IF colors>2 THEN
DO
box_y=24
IF colors=8 THEN box_x=46
END
box_cols=184%box_x
box_rows=48%box_y
DO i=0 TO colors-1
colors.i=ScreenColor(pscreen,i)
CALL SetAPen(host,i)
CALL RectFill(host,16+(i//box_cols)*box_x,56+(i%box_cols)*box_y,16+box_x+(i//box_cols)*box_x,56+box_y+(i%box_cols)*box_y)
END
CALL SetAPen(host,1)
/*
Note how the previous routine has no RETURN and so will "fall through"
to this next routine. Careful placement of routines can save lines of code.
This routine resets the color data to when the palette was last drawn.
*/
reset_colors:
DO i=0 TO colors-1
DO j=1 TO 3
colors.i.j=WORD(colors.i,j)%1
END
END
/*
This routine actually changes the colors using the "colors.i.j" data
*/
set_colors:
DO i=0 TO colors-1
CALL ScreenColor(pscreen,i,colors.i.1,colors.i.2,colors.i.3)
END
/*
Fills in the color number, RGB values, and the current color rectangle
*/
update_colors:
register=register%1
CALL Move(host,22,50)
CALL Text(host,RIGHT(register,2))
CALL Move(host,xmax-44,50)
CALL Text(host,d2x(colors.register.1)||d2x(colors.register.2)||d2x(colors.register.3))
DO i=1 TO 3
CALL Move(host,31+(i-1)*70,33)
CALL Text(host,right(colors.register.i%1,2))
END
CALL SetAPen(host,register)
CALL RectFill(host,54,43,160,51)
CALL SetAPen(host,1)
RETURN
/*
Changing RGB values - we limit them to valid values, 0 to 15
Note use of the internal message loop to speed event processing.
As long as the message remains GADGETDOWN, this routine will continue
to cycle, but if the button is released over the gadget (GADGETUP) or
has been moved off the gadget (SELECTUP) the cycling stops.
If we hadn't run ModifyHost(), SELECTUP would be replaced by MOUSEBUTTONS.
*/
gadgetdown:
PARSE ARG rgb updown .
DO icount=1
colors.register.rgb=colors.register.rgb+updown
IF colors.register.rgb<0 THEN colors.register.rgb=15
IF colors.register.rgb>15 THEN colors.register.rgb=0
CALL ScreenColor(pscreen,register,colors.register.1,colors.register.2,colors.register.3)
CALL update_colors()
IF cpu>68000 THEN CALL DELAY(2)
p=GETPKT(port)
IF p~='0000 0000'x THEN
DO
arg1=GETARG(p)
t=REPLY(p,0)
PARSE VAR arg1 arg1 .
IF arg1="GADGETUP" | arg1="SELECTUP" | arg1='MOUSEBUTTONS' THEN
LEAVE icount
END
END
RETURN
/*
Selection of the color register to change using the size of the
filled in box to figure out which color the user wants.
Selections outside the color-selection-rectangle are ignored.
*/
selectdown:
IF arg2<14 | arg2>198 | arg3<55 | arg3>103 THEN RETURN
mx=(arg2-14)%box_x
my=(arg3-55)%box_y
IF mx>=box_cols THEN mx=box_cols-1
IF my>=box_rows THEN my=box_rows-1
register=mx+my*box_cols
CALL update_colors()
RETURN
/*
Box routine to draw 2.0 style boxes.
Note that the box is 1 pixel wider than asked for on BOTH sides,
so width is really width+2 although height is correct.
Assuming register 1 is dark and register 2 is bright...
pen1 pen2 effect
---- ---- ------
1 1 plain
1 2 recessed
2 1 raised
*/
box:
ARG boxhost,pen1,pen2,upleft,uptop,width,height
CALL SetAPen(boxhost,pen2)
CALL Move(boxhost,upleft+width+1,uptop)
CALL Draw(boxhost,upleft+width+1,uptop+height)
CALL Draw(boxhost,upleft-1,uptop+height)
CALL Move(boxhost,upleft+width,uptop+1)
CALL Draw(boxhost,upleft+width,uptop+height)
CALL SetAPen(boxhost,pen1)
CALL Move(boxhost,upleft,uptop)
CALL Draw(boxhost,upleft+width,uptop)
CALL Move(boxhost,upleft,uptop+height-1)
CALL Draw(boxhost,upleft,uptop)
CALL Move(boxhost,upleft-1,uptop)
CALL Draw(boxhost,upleft-1,uptop+height)
RETURN
/*
Creates a place where messages can be recieved by rexxarplib
and acted upon. The HOST is where you direct your requests
for windows and graphics and the like. The PORT is where the
HOST returns messages about what it has done or what gadgets,
menu items, etc. have been selected by the user.
We send commands to the HOST and get messages from the PORT.
*/
setup_host:
CALL OPENPORT(port)
ADDRESS AREXX "'x=CreateHost("host","port","pscreen")'"
DO 200 WHILE ~SHOW('Ports',host)
CALL DELAY 10 /* 200 ms */
END
IF ~SHOW('Ports',host) THEN
CALL ALL_DONE('Could not open host 'host'.')
IF ~SHOW('Ports',port) THEN
CALL ALL_DONE('Could not open port 'port'.')
RETURN
/*
Opens a message window
*/
usermsg:
PARSE ARG umsg
CALL PostMsg()
CALL PostMsg(0,160,umsg,pscreen)
RETURN
/* Wait long enough for the message to be read */
waiting:
CALL DELAY(200)
CALL PostMsg()
RETURN
/*
initialize
*/
setup_variables:
register=0
x=SOURCELINE(1)
copyright=''
DO i=3 TO 7
copyright=copyright WORD(x,i)
END
copyright=CENTER(STRIP(copyright),32)'\\
© 1991 Richard Lee Stockton\'CENTER('and',32)'\
Gramma Software Systems\
17730-15th Avenue NE, Suite 223\
Seattle WA 98155-3804\
Office: (206) 363-6417\
FAX: 361-0429\
BBS: 744-1254\
Tech: 776-1253\\
FREELY DISTRIBUTABLE'
RETURN
/*
Use DOS version command to get operating system version
Redirect it to a temporary RAM file and read that.
We can get the cpu type (68000,020,030,040) using the
VERSION keyword with the PARSE command.
*/
getversions:
ADDRESS COMMAND 'version >RAM:VERSION'
x=OPEN(f,'RAM:VERSION','R')
line=READLN(f)
CALL CLOSE(f)
CALL DELETE('RAM:VERSION')
ksversion=STRIP(WORD(line,3))
PARSE VERSION . . cpu .
RETURN
/* Palette.rexx */